﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace SilverlightClientLibrary.Chat
{
    public partial class SilverlightMessageWindow : UserControl
    {
        private List<TextBlock> _textBlocks;
        private List<DateTime> _timeAdded;
        private List<TranslateTransform> _transforms;

        private TextBox _chatBox;

        private DispatcherTimer _dt;

        public event Action<string> MessageEntered;
        public bool Chatting { get; private set; }

        public SilverlightMessageWindow()
        {
            InitializeComponent();

            _textBlocks = new List<TextBlock>();
            _timeAdded = new List<DateTime>();
            _transforms = new List<TranslateTransform>();

            _chatBox = new TextBox();
            _chatBox.Width = this.LayoutRoot.Width - 40;
            _chatBox.Height = 25;
            _chatBox.Visibility = Visibility.Collapsed;
            _chatBox.HorizontalAlignment = HorizontalAlignment.Left;
            _chatBox.VerticalAlignment = VerticalAlignment.Top;
            TranslateTransform tt = new TranslateTransform();
            tt.X = 20;
            _chatBox.RenderTransform = tt;
            this.LayoutRoot.Children.Add(_chatBox);

            _dt = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(.1) };
            _dt.Tick += new EventHandler(_dt_Tick);
            _dt.Start();
        }

        public void Attach(UserControl u)
        {
            u.KeyDown += new KeyEventHandler(u_KeyDown);
        }

        private void _dt_Tick(object sender, EventArgs e)
        {
            DateTime fiveSecondsAgo = DateTime.Now.AddSeconds(-5);
            for (int i = 0; i < _textBlocks.Count; i++)
            {
                TextBlock tb = _textBlocks[i];
                DateTime timeAdded = _timeAdded[i];
                if (timeAdded < fiveSecondsAgo)
                {
                    tb.Opacity = 1 - (
                        (fiveSecondsAgo.TimeOfDay.TotalMilliseconds - timeAdded.TimeOfDay.TotalMilliseconds) /
                        5000);
                    if (tb.Opacity <= 0)
                    {
                        RemoveTextBlock(i);
                    }
                }
            }
        }

        void u_KeyDown(object sender, KeyEventArgs e)
        {
            if (Chatting)
            {
                if (e.Key == Key.Enter)
                {
                    if (_chatBox.Text.Length > 0)
                    {
                        MessageEntered(_chatBox.Text);
                        AddMessage("You: " + _chatBox.Text);
                        _chatBox.Text = "";
                    }
                    Chatting = false;
                    _chatBox.Visibility = Visibility.Collapsed;
                }
            }
            else
            {
                if (e.Key == Key.Enter)
                {
                    Chatting = true;
                    _chatBox.Visibility = Visibility.Visible;
                    _chatBox.Focus();
                }
            }
        }

        public void AddMessage(string s)
        {
            Dispatcher.BeginInvoke(new Action<string>(AddMessageSynchronously), new object[] { s });
        }

        private void AddMessageSynchronously(string s)
        {
            TextBlock tb = new TextBlock();
            tb.Text = s;
            TranslateTransform tt = new TranslateTransform();
            tt.X = 20;
            tt.Y = _textBlocks.Count * 20 + 25;
            tb.RenderTransform = tt;
            _timeAdded.Add(DateTime.Now);
            _textBlocks.Add(tb);
            _transforms.Add(tt);
            this.LayoutRoot.Children.Add(tb);

            if (_textBlocks.Count > 6)
            {
                RemoveTextBlock(0);
            }
        }

        private void ScootUp()
        {
            foreach (TranslateTransform tt in _transforms)
            {
                tt.Y -= 20;
            }
        }

        private void RemoveTextBlock(int index)
        {
            this.LayoutRoot.Children.Remove(_textBlocks[index]);
            _textBlocks.RemoveAt(index);
            _timeAdded.RemoveAt(index);
            _transforms.RemoveAt(index);
            ScootUp();
        }
    }
}
